package controllers;

import configuration.FrontContainer;
import dataContracts.AvlSLPBuildingStatistics;
import dataContracts.CartesianSLPBuildingStatistics;
import dataContracts.FileMetadata;
import database.IDBContext;
import factories.IFileInfoFactory;
import factories.IStatisticsFactory;
import handlers.IFileInfoHandler;
import models.FileInfo;
import play.Logger;
import play.mvc.Before;
import play.mvc.Controller;
import serialization.IXmlSerializer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class Import extends Controller {

    static IDBContext dbContext;

    static IStatisticsFactory statisticsFactory;

    static IFileInfoHandler fileInfoHandler;

    @Before
    static void init() {
        dbContext = FrontContainer.getInstance().get(IDBContext.class);
        statisticsFactory = FrontContainer.getInstance().get(IStatisticsFactory.class);
        fileInfoHandler = FrontContainer.getInstance().get(IFileInfoHandler.class);
    }


    static <T> T deserializeFromRequestBody(Class<T> statisticsClass) {
        IXmlSerializer xmlSerializer = FrontContainer.getInstance().get(IXmlSerializer.class);
        byte [] requestBody = readRequestBody();
        return xmlSerializer.deserialize(statisticsClass, new String(requestBody));
    }

    private static byte[] readRequestBody() {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream in = request.body;
        try {
            int data = 0;
            try {
                data = in.read();
                while(data != -1) {
                    out.write(data);
                    data = in.read();
                }
            } catch (IOException e) {
                Logger.error(e, "Read failed");
            }
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                Logger.error(e, "Close failed");
            }
        }
        return out.toByteArray();
    }


    public static void slpClassicStatistics() {
        AvlSLPBuildingStatistics statistics = deserializeFromRequestBody(AvlSLPBuildingStatistics.class);
        FileInfo fileInfo = fileInfoHandler.read(statistics.runningConfiguration.textId);
        dbContext.create(statisticsFactory.createSLPClassic(statistics, fileInfo));
    }

    public static void slpOptimalStatistics() {
        AvlSLPBuildingStatistics statistics = deserializeFromRequestBody(AvlSLPBuildingStatistics.class);
        FileInfo fileInfo = fileInfoHandler.read(statistics.runningConfiguration.textId);
        dbContext.create(statisticsFactory.createSLPOptimal(statistics, fileInfo));
    }

    public static void slpCartesianStatistics() {
        CartesianSLPBuildingStatistics statistics = deserializeFromRequestBody(CartesianSLPBuildingStatistics.class);
        FileInfo fileInfo = fileInfoHandler.read(statistics.textId);
        dbContext.create(statisticsFactory.create(statistics, fileInfo));
    }

    public static void fileMetadata() {
        FileMetadata fileMetadata = deserializeFromRequestBody(FileMetadata.class);
        IFileInfoFactory fileInfoFactory = FrontContainer.getInstance().get(IFileInfoFactory.class);
        dbContext.create(fileInfoFactory.create(fileMetadata));
    }
}
